import os
import uvicorn
import time
import logging
import asyncio
import subprocess
import json
from datetime import datetime
from fastapi import FastAPI, File, UploadFile, Form, HTTPException
from fastapi.responses import RedirectResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
import shutil

from video_agent import video_agent
from config.settings import settings
from middleware.rate_limit import rate_limiter
from utils.file_validator import file_validator

# 配置日志
logging.basicConfig(
    level=getattr(logging, settings.LOG_LEVEL),
    format=settings.LOG_FORMAT
)
logger = logging.getLogger(__name__)

# 检查 FFmpeg 是否安装
try:
    subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
    logger.info("FFmpeg 已安装")
except subprocess.CalledProcessError:
    logger.error("FFmpeg 未安装，请先安装 FFmpeg")
    raise RuntimeError("FFmpeg 未安装，请先安装 FFmpeg")
except FileNotFoundError:
    logger.error("FFmpeg 未安装，请先安装 FFmpeg")
    raise RuntimeError("FFmpeg 未安装，请先安装 FFmpeg")

app = FastAPI(title="视频处理API", description="处理视频并通过大模型获取回复的API服务")

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 挂载静态文件
app.mount("/static", StaticFiles(directory="static", html=True), name="static")

# 创建上传文件存储目录
try:
    os.makedirs(settings.UPLOAD_DIR, exist_ok=True)
except Exception as e:
    logger.error(f"创建上传目录失败: {str(e)}")
    raise

async def convert_to_mp4(input_path: str) -> str:
    """将视频转换为 MP4 格式"""
    try:
        output_path = input_path.replace('.webm', '.mp4')
        # 使用 FFmpeg 转换视频
        cmd = [
            'ffmpeg', '-i', input_path,
            '-c:v', 'libx264',  # 使用 H.264 编码
            '-preset', 'medium',  # 编码速度预设
            '-crf', '23',  # 视频质量
            '-c:a', 'aac',  # 音频编码
            '-b:a', '128k',  # 音频比特率
            output_path
        ]
        
        # 执行转换命令
        process = await asyncio.create_subprocess_exec(
            *cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE
        )
        stdout, stderr = await process.communicate()
        
        if process.returncode != 0:
            raise Exception(f"FFmpeg 转换失败: {stderr.decode()}")
        
        return output_path
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"视频转换失败: {str(e)}"
        )

@app.post("/upload_video")
async def upload_video(
    file: UploadFile = File(...),
    text_prompt: str = Form("描述这个视频的具体过程"),
):
    start_time = time.time()
    temp_file_path = None
    converted_file_path = None
    
    try:
        # 验证文件
        await file_validator.validate(file)
        
        # 保存临时文件
        filename = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_video.webm"
        temp_file_path = os.path.join(settings.UPLOAD_DIR, filename)
        
        with open(temp_file_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        logger.info(f"视频文件已保存: {temp_file_path}")
        
        # 转换为 MP4
        converted_file_path = await convert_to_mp4(temp_file_path)
        logger.info(f"视频已转换为 MP4: {converted_file_path}")
        
        # 处理视频
        result = await video_agent.process_video(converted_file_path, text_prompt)
        logger.info(f"视频处理完成，结果状态: {'成功' if result.get('success') else '失败'}")
        
        # 输出返回结果的完整内容进行调试
        logger.info(f"处理结果: {result}")
        
        # 计算处理时间
        process_time = time.time() - start_time
        logger.info(f"视频处理耗时: {process_time:.2f}秒")
        
        # 检查结果
        if not result or not result.get("success"):
            logger.error("视频处理失败")
            return {
                "success": False,
                "error": "视频处理失败",
                "text": "视频处理失败，请重试"
            }
        
        # 从data字段中获取text (适应实际返回的数据结构)
        if "data" in result and isinstance(result["data"], dict) and "text" in result["data"]:
            response_text = result["data"]["text"]
        else:
            response_text = result.get("text", "")
            
        logger.info(f"从结果中提取的响应文本: '{response_text}'")
        
        # 如果文本为空，使用默认消息
        if not response_text:
            logger.warning("视频处理成功但响应文本为空")
            response_text = "视频处理成功，但内容为空"
        
        # 返回结果
        response = {
            "success": True,
            "text": response_text,
            "process_time": f"{process_time:.2f}秒"
        }
        logger.info(f"返回给前端的响应: {response}")
        
        return response
        
    except Exception as e:
        logger.error(f"处理视频时出错: {str(e)}")
        return {
            "success": False,
            "error": str(e),
            "text": "视频处理失败，请重试"
        }
        
    finally:
        # 清理临时文件
        if temp_file_path and os.path.exists(temp_file_path):
            os.remove(temp_file_path)
            logger.info(f"临时 WebM 文件已删除: {temp_file_path}")
        if converted_file_path and os.path.exists(converted_file_path):
            os.remove(converted_file_path)
            logger.info(f"临时 MP4 文件已删除: {converted_file_path}")

@app.get("/health")
async def health_check():
    """健康检查端点"""
    return {"status": "healthy"}

@app.get("/")
async def redirect_to_index():
    """重定向到前端页面"""
    return RedirectResponse(url="/static/index.html")

if __name__ == "__main__":
    # 获取端口，默认为8000
    port = int(os.environ.get("PORT", 8000))
    
    # 启动服务器
    uvicorn.run(app, host="0.0.0.0", port=port) 